package com.loveprogrammer.base.network.support;

import com.loveprogrammer.base.bean.session.Session;
import com.loveprogrammer.pojo.StringMessage;
import com.loveprogrammer.utils.ChannelUtils;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName SessionManager
 * @Description 会话管理类
 * @Author admin
 * @Date 2024/2/4 17:44
 * @Version 1.0
 */
public class SessionManager {
    private static final Logger logger = LoggerFactory.getLogger(SessionManager.class);
    private static final SessionManager instance = new SessionManager();

    public static SessionManager getInstance() {
        return instance;
    }

    private SessionManager() {
        logger.info("SessionManager init success");
    }

    /***
     * 会话 map
     */
    public final static Map<Integer, Session> CLIENT_SESSION_MAP = new ConcurrentSkipListMap<>();

    /***
     * CHANNEL map
     */
    public final static Map<String, Integer> CHANNEL_ID_MAP = new ConcurrentHashMap<>();

    private final static AtomicInteger CLIENT_ATOMIC_ID = new AtomicInteger(1);

    public final static int getClientId() {
        return CLIENT_ATOMIC_ID.getAndIncrement();
    }

    public Session getSession(Integer id) {
        return CLIENT_SESSION_MAP.get(id);
    }

    public Session getById(Integer id) {
        return CLIENT_SESSION_MAP.get(id);
    }

    public int getId(Channel channel) {
        String longId = channel.id().asLongText();
        Integer clientId = CHANNEL_ID_MAP.get(longId);
        if (null == clientId) {
            clientId = getClientId();
            CHANNEL_ID_MAP.put(longId, clientId);
        }
        return clientId;
    }

    /**
     * 创建session
     *
     * @param channel 与客户端连接的管道
     * @return session
     */
    public Session create(Channel channel) {
        Session session = getSessionByChannel(channel);
        if (session == null) {
            int id = getId(channel);
            session = new Session(id,channel);
            CLIENT_SESSION_MAP.put(id,session);
            logger.info("session 创建成功");
        } else {
            logger.error("新连接建立时已存在Session，注意排查原因 " + channel.toString());
        }
        return session;
    }

//    /**
//     * 注册sesson
//     *
//     * @param session session
//     * @param user    用户
//     */
//    public void register(Session session, User user) {
//        session.registerUser(user);
//        uidSessionMap.put(session.getUser().getId(), session);
//    }

    /**
     * 通过channel关闭session
     *
     * @param channel 与客户端连接的管道
     */
    public void close(Channel channel) {
        Session session = getSessionByChannel(channel);
        if (session != null) {
            close(session);
        }
    }

    /**
     * 关闭session
     *
     * @param session 要关闭的session
     */
    private void close(Session session) {
        unregister(session);
        session.close();
        logger.info("session close success");
    }

    /**
     * 将之前注册好的session从map中移除
     *
     * @param session 将之前注册好的session从map中移除
     */
    private void unregister(Session session) {
        if (session != null) {
            int sessionId = session.getId();
            CLIENT_SESSION_MAP.remove(sessionId);
            CLIENT_SESSION_MAP.remove(sessionId);
            logger.info("Session unregister, userId={}, sessionId={}", session.getUserId(), sessionId);
        }
    }

    public Session getSessionByChannel(Channel channel) {
        int id = getId(channel);
        return getById(id);
    }

    public void sendMessage(Channel channel, StringMessage msg) {
        ChannelUtils.pushToClient(channel,msg);

    }

    public void sendMessage(Session session, StringMessage msg) {
        session.getChannel().writeAndFlush(msg);
    }
}
